/**
 * 
 */
package com.monkeyboy.security.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.social.security.SocialUser;
import org.springframework.social.security.SocialUserDetails;
import org.springframework.social.security.SocialUserDetailsService;
import org.springframework.stereotype.Component;

/**
 * @Description <br>
 *              UserDetailsService:表但登录时候用的，由于表单登录传入的是用户名<br>
 *              SocialUserDetailsService:第三方登录时候的用户信息认证，传入的是userId<br>
 * @author Gavin<br>
 *         2019年8月25日
 */
@Component
public class MyUserDetailsService implements UserDetailsService, SocialUserDetailsService {
	private Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private PasswordEncoder passwordEncoder;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.core.userdetails.UserDetailsService#
	 * loadUserByUsername(java.lang.String)
	 */
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		logger.info("登录用户名：{}", username);
		// 根据用户名查找用户信息
		/**
		 * UsernamePasswordAuthenticationFilter:用户名密码是通过这个过滤器来处理的<br>
		 * 用户名：页面获取<br>
		 * 密码:数据库读取（校验密码的过程交给springsecurity来做，这儿填写的不是页面的密码是数据库中的密码）<br>
		 * 权限：数据库读取<br>
		 * note:如果校验通过会把用户信息存入到session中,User对象中查看源代码可以知道构造函数里面可以添加其它参数来控制用户密码过期，身份过期，是否被锁定这些状态<br>
		 * 密码的加密和解密：PasswordEncoder.encode(CharSequence
		 * rawPassword)方法加密，解密的时候springsecurity会自动把从这里传入的数据库密码和用户表单上面输入的密码进行比对，通过PasswordEncoder.matches(CharSequence
		 * rawPassword, String encodedPassword)方法<br>
		 * passwordEncoder.encode("123456"):利用springsecurity进行密码加密，这儿是为了演示，实际是在用户注册的时候进行加密然后存入到数据库中<br>
		 */
		return new User(username, passwordEncoder.encode("123456"), true, // 是否可用
				true, // 是否登录过期
				true, // 密码是否过期
				true, // 是否被锁定
				AuthorityUtils.commaSeparatedStringToAuthorityList("admin,system,user"));
		
		//这儿都返回socialUser便于测试social的开发
//		return new SocialUser(username, passwordEncoder.encode("123456"), true,
//				true, // 是否登录过期
//				true, // 密码是否过期
//				true, // 是否被锁定
//				AuthorityUtils.commaSeparatedStringToAuthorityList(""));
	}

	/*
	 * 社交登录，根据springsocial根据openid从数据库中查询到userId然后构建新的用户信息
	 */
	@Override
	public SocialUserDetails loadUserByUserId(String userId) throws UsernameNotFoundException {
		logger.info("============================社交登录的用户名:{}", userId);
		return new SocialUser(userId, passwordEncoder.encode("123456"), true, // 是否可用
				true, // 是否登录过期
				true, // 密码是否过期
				true, // 是否被锁定
				AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
	}

}
